package com.nlp.cahe;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class LRUCache<K,V> extends LinkedHashMap<K, V> {
	private static final long serialVersionUID = 1L;
	
	private static final float DEFAULT_LOAD_FACTOR = 1f;

	private final int maxCapacity;
	private final ReadWriteLock lock = new ReentrantReadWriteLock();
	public LRUCache(int maxCapacity) {
		/**
		 * 第3个参数
		 * false表示维持插入顺序，这样最早插入的将最先被移除。
		 * true表示维持访问顺序，调用get方法后，会将这次访问
		 * 的元素移至链表尾部，删除老元素时会删除表头元素。
		 */
		super(maxCapacity, DEFAULT_LOAD_FACTOR, true);
		this.maxCapacity = maxCapacity;
	}
	@Override
	public V get(Object key) {
		try {
			lock.readLock().lock();
			return super.get(key);
		} finally {
			lock.readLock().unlock();
		}
	}
	@Override
	protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
		//元素个数达到maxCapacity 删除老元素
		return size() > maxCapacity;
	}
	@Override
	public boolean containsKey(Object key) {
		try {
			lock.readLock().lock();
			return super.containsKey(key);
		} finally {
			lock.readLock().unlock();
		}
	}
	
	public int size() {
		try {
			lock.readLock().lock();
			return super.size();
		} finally {
			lock.readLock().unlock();
		}
	}
	@Override
	public void clear() {
		try {
			lock.writeLock().lock();
			super.clear();
		} finally {
			lock.writeLock().unlock();
		}
	}
	
	public ArrayList<Map.Entry<K, V>> getAll() {
		try {
			lock.readLock().lock();
			return new ArrayList<Map.Entry<K, V>>(super.entrySet());
		} finally {
			lock.readLock().unlock();
		}
	}
	@Override
	public V put(K key, V value) {
		try {
			lock.writeLock().lock();
			return super.put(key, value);
		} finally {
			lock.writeLock().unlock();
		}
	}
}
